home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / gettext / intl / printf-parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  2010-09-19  |  21.1 KB  |  629 lines

  1. /* Formatted output to strings.
  2.    Copyright (C) 1999-2000, 2002-2003, 2006-2008 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify it
  5.    under the terms of the GNU Library General Public License as published
  6.    by the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.    Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  17.    USA.  */
  18.  
  19. /* This file can be parametrized with the following macros:
  20.      CHAR_T             The element type of the format string.
  21.      CHAR_T_ONLY_ASCII  Set to 1 to enable verification that all characters
  22.                         in the format string are ASCII.
  23.      DIRECTIVE          Structure denoting a format directive.
  24.                         Depends on CHAR_T.
  25.      DIRECTIVES         Structure denoting the set of format directives of a
  26.                         format string.  Depends on CHAR_T.
  27.      PRINTF_PARSE       Function that parses a format string.
  28.                         Depends on CHAR_T.
  29.      STATIC             Set to 'static' to declare the function static.
  30.      ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.  */
  31.  
  32. #ifndef PRINTF_PARSE
  33. # include <config.h>
  34. #endif
  35.  
  36. /* Specification.  */
  37. #ifndef PRINTF_PARSE
  38. # include "printf-parse.h"
  39. #endif
  40.  
  41. /* Default parameters.  */
  42. #ifndef PRINTF_PARSE
  43. # define PRINTF_PARSE printf_parse
  44. # define CHAR_T char
  45. # define DIRECTIVE char_directive
  46. # define DIRECTIVES char_directives
  47. #endif
  48.  
  49. /* Get size_t, NULL.  */
  50. #include <stddef.h>
  51.  
  52. /* Get intmax_t.  */
  53. #if defined IN_LIBINTL || defined IN_LIBASPRINTF
  54. # if HAVE_STDINT_H_WITH_UINTMAX
  55. #  include <stdint.h>
  56. # endif
  57. # if HAVE_INTTYPES_H_WITH_UINTMAX
  58. #  include <inttypes.h>
  59. # endif
  60. #else
  61. # include <stdint.h>
  62. #endif
  63.  
  64. /* malloc(), realloc(), free().  */
  65. #include <stdlib.h>
  66.  
  67. /* errno.  */
  68. #include <errno.h>
  69.  
  70. /* Checked size_t computations.  */
  71. #include "xsize.h"
  72.  
  73. #if CHAR_T_ONLY_ASCII
  74. /* c_isascii().  */
  75. # include "c-ctype.h"
  76. #endif
  77.  
  78. #ifdef STATIC
  79. STATIC
  80. #endif
  81. int
  82. PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
  83. {
  84.   const CHAR_T *cp = format;            /* pointer into format */
  85.   size_t arg_posn = 0;          /* number of regular arguments consumed */
  86.   size_t d_allocated;                   /* allocated elements of d->dir */
  87.   size_t a_allocated;                   /* allocated elements of a->arg */
  88.   size_t max_width_length = 0;
  89.   size_t max_precision_length = 0;
  90.  
  91.   d->count = 0;
  92.   d_allocated = 1;
  93.   d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
  94.   if (d->dir == NULL)
  95.     /* Out of memory.  */
  96.     goto out_of_memory_1;
  97.  
  98.   a->count = 0;
  99.   a_allocated = 0;
  100.   a->arg = NULL;
  101.  
  102. #define REGISTER_ARG(_index_,_type_) \
  103.   {                                                                     \
  104.     size_t n = (_index_);                                               \
  105.     if (n >= a_allocated)                                               \
  106.       {                                                                 \
  107.         size_t memory_size;                                             \
  108.         argument *memory;                                               \
  109.                                                                         \
  110.         a_allocated = xtimes (a_allocated, 2);                          \
  111.         if (a_allocated <= n)                                           \
  112.           a_allocated = xsum (n, 1);                                    \
  113.         memory_size = xtimes (a_allocated, sizeof (argument));          \
  114.         if (size_overflow_p (memory_size))                              \
  115.           /* Overflow, would lead to out of memory.  */                 \
  116.           goto out_of_memory;                                           \
  117.         memory = (argument *) (a->arg                                   \
  118.                                ? realloc (a->arg, memory_size)          \
  119.                                : malloc (memory_size));                 \
  120.         if (memory == NULL)                                             \
  121.           /* Out of memory.  */                                         \
  122.           goto out_of_memory;                                           \
  123.         a->arg = memory;                                                \
  124.       }                                                                 \
  125.     while (a->count <= n)                                               \
  126.       a->arg[a->count++].type = TYPE_NONE;                              \
  127.     if (a->arg[n].type == TYPE_NONE)                                    \
  128.       a->arg[n].type = (_type_);                                        \
  129.     else if (a->arg[n].type != (_type_))                                \
  130.       /* Ambiguous type for positional argument.  */                    \
  131.       goto error;                                                       \
  132.   }
  133.  
  134.   while (*cp != '\0')
  135.     {
  136.       CHAR_T c = *cp++;
  137.       if (c == '%')
  138.         {
  139.           size_t arg_index = ARG_NONE;
  140.           DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
  141.  
  142.           /* Initialize the next directive.  */
  143.           dp->dir_start = cp - 1;
  144.           dp->flags = 0;
  145.           dp->width_start = NULL;
  146.           dp->width_end = NULL;
  147.           dp->width_arg_index = ARG_NONE;
  148.           dp->precision_start = NULL;
  149.           dp->precision_end = NULL;
  150.           dp->precision_arg_index = ARG_NONE;
  151.           dp->arg_index = ARG_NONE;
  152.  
  153.           /* Test for positional argument.  */
  154.           if (*cp >= '0' && *cp <= '9')
  155.             {
  156.               const CHAR_T *np;
  157.  
  158.               for (np = cp; *np >= '0' && *np <= '9'; np++)
  159.                 ;
  160.               if (*np == '$')
  161.                 {
  162.                   size_t n = 0;
  163.  
  164.                   for (np = cp; *np >= '0' && *np <= '9'; np++)
  165.                     n = xsum (xtimes (n, 10), *np - '0');
  166.                   if (n == 0)
  167.                     /* Positional argument 0.  */
  168.                     goto error;
  169.                   if (size_overflow_p (n))
  170.                     /* n too large, would lead to out of memory later.  */
  171.                     goto error;
  172.                   arg_index = n - 1;
  173.                   cp = np + 1;
  174.                 }
  175.             }
  176.  
  177.           /* Read the flags.  */
  178.           for (;;)
  179.             {
  180.               if (*cp == '\'')
  181.                 {
  182.                   dp->flags |= FLAG_GROUP;
  183.                   cp++;
  184.                 }
  185.               else if (*cp == '-')
  186.                 {
  187.                   dp->flags |= FLAG_LEFT;
  188.                   cp++;
  189.                 }
  190.               else if (*cp == '+')
  191.                 {
  192.                   dp->flags |= FLAG_SHOWSIGN;
  193.                   cp++;
  194.                 }
  195.               else if (*cp == ' ')
  196.                 {
  197.                   dp->flags |= FLAG_SPACE;
  198.                   cp++;
  199.                 }
  200.               else if (*cp == '#')
  201.                 {
  202.                   dp->flags |= FLAG_ALT;
  203.                   cp++;
  204.                 }
  205.               else if (*cp == '0')
  206.                 {
  207.                   dp->flags |= FLAG_ZERO;
  208.                   cp++;
  209.                 }
  210.               else
  211.                 break;
  212.             }
  213.  
  214.           /* Parse the field width.  */
  215.           if (*cp == '*')
  216.             {
  217.               dp->width_start = cp;
  218.               cp++;
  219.               dp->width_end = cp;
  220.               if (max_width_length < 1)
  221.                 max_width_length = 1;
  222.  
  223.               /* Test for positional argument.  */
  224.               if (*cp >= '0' && *cp <= '9')
  225.                 {
  226.                   const CHAR_T *np;
  227.  
  228.                   for (np = cp; *np >= '0' && *np <= '9'; np++)
  229.                     ;
  230.                   if (*np == '$')
  231.                     {
  232.                       size_t n = 0;
  233.  
  234.                       for (np = cp; *np >= '0' && *np <= '9'; np++)
  235.                         n = xsum (xtimes (n, 10), *np - '0');
  236.                       if (n == 0)
  237.                         /* Positional argument 0.  */
  238.                         goto error;
  239.                       if (size_overflow_p (n))
  240.                         /* n too large, would lead to out of memory later.  */
  241.                         goto error;
  242.                       dp->width_arg_index = n - 1;
  243.                       cp = np + 1;
  244.                     }
  245.                 }
  246.               if (dp->width_arg_index == ARG_NONE)
  247.                 {
  248.                   dp->width_arg_index = arg_posn++;
  249.                   if (dp->width_arg_index == ARG_NONE)
  250.                     /* arg_posn wrapped around.  */
  251.                     goto error;
  252.                 }
  253.               REGISTER_ARG (dp->width_arg_index, TYPE_INT);
  254.             }
  255.           else if (*cp >= '0' && *cp <= '9')
  256.             {
  257.               size_t width_length;
  258.  
  259.               dp->width_start = cp;
  260.               for (; *cp >= '0' && *cp <= '9'; cp++)
  261.                 ;
  262.               dp->width_end = cp;
  263.               width_length = dp->width_end - dp->width_start;
  264.               if (max_width_length < width_length)
  265.                 max_width_length = width_length;
  266.             }
  267.  
  268.           /* Parse the precision.  */
  269.           if (*cp == '.')
  270.             {
  271.               cp++;
  272.               if (*cp == '*')
  273.                 {
  274.                   dp->precision_start = cp - 1;
  275.                   cp++;
  276.                   dp->precision_end = cp;
  277.                   if (max_precision_length < 2)
  278.                     max_precision_length = 2;
  279.  
  280.                   /* Test for positional argument.  */
  281.                   if (*cp >= '0' && *cp <= '9')
  282.                     {
  283.                       const CHAR_T *np;
  284.  
  285.                       for (np = cp; *np >= '0' && *np <= '9'; np++)
  286.                         ;
  287.                       if (*np == '$')
  288.                         {
  289.                           size_t n = 0;
  290.  
  291.                           for (np = cp; *np >= '0' && *np <= '9'; np++)
  292.                             n = xsum (xtimes (n, 10), *np - '0');
  293.                           if (n == 0)
  294.                             /* Positional argument 0.  */
  295.                             goto error;
  296.                           if (size_overflow_p (n))
  297.                             /* n too large, would lead to out of memory
  298.                                later.  */
  299.                             goto error;
  300.                           dp->precision_arg_index = n - 1;
  301.                           cp = np + 1;
  302.                         }
  303.                     }
  304.                   if (dp->precision_arg_index == ARG_NONE)
  305.                     {
  306.                       dp->precision_arg_index = arg_posn++;
  307.                       if (dp->precision_arg_index == ARG_NONE)
  308.                         /* arg_posn wrapped around.  */
  309.                         goto error;
  310.                     }
  311.                   REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
  312.                 }
  313.               else
  314.                 {
  315.                   size_t precision_length;
  316.  
  317.                   dp->precision_start = cp - 1;
  318.                   for (; *cp >= '0' && *cp <= '9'; cp++)
  319.                     ;
  320.                   dp->precision_end = cp;
  321.                   precision_length = dp->precision_end - dp->precision_start;
  322.                   if (max_precision_length < precision_length)
  323.                     max_precision_length = precision_length;
  324.                 }
  325.             }
  326.  
  327.           {
  328.             arg_type type;
  329.  
  330.             /* Parse argument type/size specifiers.  */
  331.             {
  332.               int flags = 0;
  333.  
  334.               for (;;)
  335.                 {
  336.                   if (*cp == 'h')
  337.                     {
  338.                       flags |= (1 << (flags & 1));
  339.                       cp++;
  340.                     }
  341.                   else if (*cp == 'L')
  342.                     {
  343.                       flags |= 4;
  344.                       cp++;
  345.                     }
  346.                   else if (*cp == 'l')
  347.                     {
  348.                       flags += 8;
  349.                       cp++;
  350.                     }
  351.                   else if (*cp == 'j')
  352.                     {
  353.                       if (sizeof (intmax_t) > sizeof (long))
  354.                         {
  355.                           /* intmax_t = long long */
  356.                           flags += 16;
  357.                         }
  358.                       else if (sizeof (intmax_t) > sizeof (int))
  359.                         {
  360.                           /* intmax_t = long */
  361.                           flags += 8;
  362.                         }
  363.                       cp++;
  364.                     }
  365.                   else if (*cp == 'z' || *cp == 'Z')
  366.                     {
  367.                       /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
  368.                          because the warning facility in gcc-2.95.2 understands
  369.                          only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
  370.                       if (sizeof (size_t) > sizeof (long))
  371.                         {
  372.                           /* size_t = long long */
  373.                           flags += 16;
  374.                         }
  375.                       else if (sizeof (size_t) > sizeof (int))
  376.                         {
  377.                           /* size_t = long */
  378.                           flags += 8;
  379.                         }
  380.                       cp++;
  381.                     }
  382.                   else if (*cp == 't')
  383.                     {
  384.                       if (sizeof (ptrdiff_t) > sizeof (long))
  385.                         {
  386.                           /* ptrdiff_t = long long */
  387.                           flags += 16;
  388.                         }
  389.                       else if (sizeof (ptrdiff_t) > sizeof (int))
  390.                         {
  391.                           /* ptrdiff_t = long */
  392.                           flags += 8;
  393.                         }
  394.                       cp++;
  395.                     }
  396. #if defined __APPLE__ && defined __MACH__
  397.                   /* On MacOS X 10.3, PRIdMAX is defined as "qd".
  398.                      We cannot change it to "lld" because PRIdMAX must also
  399.                      be understood by the system's printf routines.  */
  400.                   else if (*cp == 'q')
  401.                     {
  402.                       if (64 / 8 > sizeof (long))
  403.                         {
  404.                           /* int64_t = long long */
  405.                           flags += 16;
  406.                         }
  407.                       else
  408.                         {
  409.                           /* int64_t = long */
  410.                           flags += 8;
  411.                         }
  412.                       cp++;
  413.                     }
  414. #endif
  415. #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  416.                   /* On native Win32, PRIdMAX is defined as "I64d".
  417.                      We cannot change it to "lld" because PRIdMAX must also
  418.                      be understood by the system's printf routines.  */
  419.                   else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
  420.                     {
  421.                       if (64 / 8 > sizeof (long))
  422.                         {
  423.                           /* __int64 = long long */
  424.                           flags += 16;
  425.                         }
  426.                       else
  427.                         {
  428.                           /* __int64 = long */
  429.                           flags += 8;
  430.                         }
  431.                       cp += 3;
  432.                     }
  433. #endif
  434.                   else
  435.                     break;
  436.                 }
  437.  
  438.               /* Read the conversion character.  */
  439.               c = *cp++;
  440.               switch (c)
  441.                 {
  442.                 case 'd': case 'i':
  443. #if HAVE_LONG_LONG_INT
  444.                   /* If 'long long' exists and is larger than 'long':  */
  445.                   if (flags >= 16 || (flags & 4))
  446.                     type = TYPE_LONGLONGINT;
  447.                   else
  448. #endif
  449.                   /* If 'long long' exists and is the same as 'long', we parse
  450.                      "lld" into TYPE_LONGINT.  */
  451.                   if (flags >= 8)
  452.                     type = TYPE_LONGINT;
  453.                   else if (flags & 2)
  454.                     type = TYPE_SCHAR;
  455.                   else if (flags & 1)
  456.                     type = TYPE_SHORT;
  457.                   else
  458.                     type = TYPE_INT;
  459.                   break;
  460.                 case 'o': case 'u': case 'x': case 'X':
  461. #if HAVE_LONG_LONG_INT
  462.                   /* If 'long long' exists and is larger than 'long':  */
  463.                   if (flags >= 16 || (flags & 4))
  464.                     type = TYPE_ULONGLONGINT;
  465.                   else
  466. #endif
  467.                   /* If 'unsigned long long' exists and is the same as
  468.                      'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
  469.                   if (flags >= 8)
  470.                     type = TYPE_ULONGINT;
  471.                   else if (flags & 2)
  472.                     type = TYPE_UCHAR;
  473.                   else if (flags & 1)
  474.                     type = TYPE_USHORT;
  475.                   else
  476.                     type = TYPE_UINT;
  477.                   break;
  478.                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
  479.                 case 'a': case 'A':
  480.                   if (flags >= 16 || (flags & 4))
  481.                     type = TYPE_LONGDOUBLE;
  482.                   else
  483.                     type = TYPE_DOUBLE;
  484.                   break;
  485.                 case 'c':
  486.                   if (flags >= 8)
  487. #if HAVE_WINT_T
  488.                     type = TYPE_WIDE_CHAR;
  489. #else
  490.                     goto error;
  491. #endif
  492.                   else
  493.                     type = TYPE_CHAR;
  494.                   break;
  495. #if HAVE_WINT_T
  496.                 case 'C':
  497.                   type = TYPE_WIDE_CHAR;
  498.                   c = 'c';
  499.                   break;
  500. #endif
  501.                 case 's':
  502.                   if (flags >= 8)
  503. #if HAVE_WCHAR_T
  504.                     type = TYPE_WIDE_STRING;
  505. #else
  506.                     goto error;
  507. #endif
  508.                   else
  509.                     type = TYPE_STRING;
  510.                   break;
  511. #if HAVE_WCHAR_T
  512.                 case 'S':
  513.                   type = TYPE_WIDE_STRING;
  514.                   c = 's';
  515.                   break;
  516. #endif
  517.                 case 'p':
  518.                   type = TYPE_POINTER;
  519.                   break;
  520.                 case 'n':
  521. #if HAVE_LONG_LONG_INT
  522.                   /* If 'long long' exists and is larger than 'long':  */
  523.                   if (flags >= 16 || (flags & 4))
  524.                     type = TYPE_COUNT_LONGLONGINT_POINTER;
  525.                   else
  526. #endif
  527.                   /* If 'long long' exists and is the same as 'long', we parse
  528.                      "lln" into TYPE_COUNT_LONGINT_POINTER.  */
  529.                   if (flags >= 8)
  530.                     type = TYPE_COUNT_LONGINT_POINTER;
  531.                   else if (flags & 2)
  532.                     type = TYPE_COUNT_SCHAR_POINTER;
  533.                   else if (flags & 1)
  534.                     type = TYPE_COUNT_SHORT_POINTER;
  535.                   else
  536.                     type = TYPE_COUNT_INT_POINTER;
  537.                   break;
  538. #if ENABLE_UNISTDIO
  539.                 /* The unistdio extensions.  */
  540.                 case 'U':
  541.                   if (flags >= 16)
  542.                     type = TYPE_U32_STRING;
  543.                   else if (flags >= 8)
  544.                     type = TYPE_U16_STRING;
  545.                   else
  546.                     type = TYPE_U8_STRING;
  547.                   break;
  548. #endif
  549.                 case '%':
  550.                   type = TYPE_NONE;
  551.                   break;
  552.                 default:
  553.                   /* Unknown conversion character.  */
  554.                   goto error;
  555.                 }
  556.             }
  557.  
  558.             if (type != TYPE_NONE)
  559.               {
  560.                 dp->arg_index = arg_index;
  561.                 if (dp->arg_index == ARG_NONE)
  562.                   {
  563.                     dp->arg_index = arg_posn++;
  564.                     if (dp->arg_index == ARG_NONE)
  565.                       /* arg_posn wrapped around.  */
  566.                       goto error;
  567.                   }
  568.                 REGISTER_ARG (dp->arg_index, type);
  569.               }
  570.             dp->conversion = c;
  571.             dp->dir_end = cp;
  572.           }
  573.  
  574.           d->count++;
  575.           if (d->count >= d_allocated)
  576.             {
  577.               size_t memory_size;
  578.               DIRECTIVE *memory;
  579.  
  580.               d_allocated = xtimes (d_allocated, 2);
  581.               memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
  582.               if (size_overflow_p (memory_size))
  583.                 /* Overflow, would lead to out of memory.  */
  584.                 goto out_of_memory;
  585.               memory = (DIRECTIVE *) realloc (d->dir, memory_size);
  586.               if (memory == NULL)
  587.                 /* Out of memory.  */
  588.                 goto out_of_memory;
  589.               d->dir = memory;
  590.             }
  591.         }
  592. #if CHAR_T_ONLY_ASCII
  593.       else if (!c_isascii (c))
  594.         {
  595.           /* Non-ASCII character.  Not supported.  */
  596.           goto error;
  597.         }
  598. #endif
  599.     }
  600.   d->dir[d->count].dir_start = cp;
  601.  
  602.   d->max_width_length = max_width_length;
  603.   d->max_precision_length = max_precision_length;
  604.   return 0;
  605.  
  606. error:
  607.   if (a->arg)
  608.     free (a->arg);
  609.   if (d->dir)
  610.     free (d->dir);
  611.   errno = EINVAL;
  612.   return -1;
  613.  
  614. out_of_memory:
  615.   if (a->arg)
  616.     free (a->arg);
  617.   if (d->dir)
  618.     free (d->dir);
  619. out_of_memory_1:
  620.   errno = ENOMEM;
  621.   return -1;
  622. }
  623.  
  624. #undef PRINTF_PARSE
  625. #undef DIRECTIVES
  626. #undef DIRECTIVE
  627. #undef CHAR_T_ONLY_ASCII
  628. #undef CHAR_T
  629.